#define		DEF_API_EXPORT		1
#define		DEF_REC_LEN			1500

#include	"MotorCtrl.h"
#include	"stdafx.h"
#include	<stdio.h>
#include	<math.h>
#include	<process.h>

#include	<WinSock2.h>
#pragma		comment(lib, "ws2_32.lib")

//#include "IniCtrl.h"
//#pragma comment(lib, "IniCtrl.lib")

#define CONNECTFAILERROR  -1
#define BECONTROLLEDERROR -2


union _DataChange
{
	int nVal;
	float fVal;
	char chVal[4];
};
_DataChange _dc;

// HWND	hMsgWnd		= NULL;
HANDLE	hThread		= NULL;
SOCKET	sServer		= 0;
int		nThreadRun	= 0;
BYTE	chData[20]	= {0};
int		bOnline[3]	= {0};
int		bMoving[3]	= {0};
int		bIsZero[3]	= {0};	
int		bIsSin[3]	= {0};
int		bStop[3]	= {0};
int		bAbs[3]		= {1, 1, 1};
double	fPos[3]		= {0};
double	fPosOp[3]	= {0};
double	fPosOut[3]	= {0};
double	fSetRatio[3]= {175, 175, 1};
double	fSpd[2]		= {0};
int		nXOffSet[11] = {0};	// 0.1mm
int		nYOffSet[11] = {0};
_SDK_CALLBACK_RECV	funRecv = NULL;


BYTE GetSum(BYTE *chBuf, int nLen)
{
	BYTE chRtn = chBuf[1];
	
	for (int i=2; i<nLen; i++)
	{
		chRtn += chBuf[i];
	}
	
	return chRtn;
}






int GetNewPos(int nSetPos, int iAxis)
{
	int nMarkCnt;
	int nMark;
	
	if (nSetPos >= -30)
	{
		nMarkCnt = (nSetPos + 30) / 1000 + 5;
		nMark	 = (nSetPos + 30) / 1000 * 1000;
	}
	else
	{
		nMarkCnt = (nSetPos - 30) / 1000 + 5;
		nMark	 = (nSetPos - 30) / 1000 * 1000;
	}
	
	if (nSetPos >= nMark - 30 && nSetPos <= nMark + 30)
	{
		if (iAxis == 1)
		{
			return nXOffSet[nMarkCnt];
		}
		else if (iAxis == 2)
		{
			return nYOffSet[nMarkCnt];
		}
	}
	
	return 0;
}

DEF_API_EXP MotionRegisterCallBack_Recv(_SDK_CALLBACK_RECV fun)
{
	funRecv = fun;
	
	return (fun != NULL);
}

//eb0000000000000000000000000000000000aaff
//eb0808081027000000000000000000000000aaff
unsigned int __stdcall ThreadLoop_UdpClient(PVOID pVoid)
{
	BYTE		chBuf[DEF_REC_LEN];
	int			nRecLen;
	int			nFromLen;
	SOCKADDR_IN	sAddr;

	while (nThreadRun == 1)
	{
// 		funRecv(bStop, bIsZero, bIsSin, bAbs, fPosOut, fSpd);

		nFromLen = sizeof(sAddr);
		nRecLen = recvfrom(sServer, (char *)chBuf, DEF_REC_LEN, 0, (sockaddr *)&sAddr, &nFromLen);
		if (nRecLen == SOCKET_ERROR)
		{
			return FALSE;
		}
		
		if (nRecLen == 20)
		{
			if (chBuf[0] == 0xeb && chBuf[19] == 0xff)
			{
				if (chBuf[18] == GetSum(chBuf, 18) || chBuf[18] == 0xAA)
				{
					for (int i=0; i<3; i++)
					{
						bOnline[i] = (chBuf[i + 1])			% 2;
						bMoving[i] = (chBuf[i + 1] >> 1)	% 2;
						bIsZero[i] = (chBuf[i + 1] >> 2)	% 4;
						bIsSin [i] = (chBuf[i + 1] >> 4)	% 4;
					}
					
					memcpy(_dc.chVal, chBuf + 4, 4);
					fPos[0] = _dc.nVal / 100.0;
					fSpd[0] = double((short)(chBuf[8] + chBuf[9] * 0x100) / 10.0) / fSetRatio[0];
					
					memcpy(_dc.chVal, chBuf + 10, 4);
					fPos[1] = _dc.nVal / 100.0;
					fSpd[1] = double((short)(chBuf[14] + chBuf[15] * 0x100) / 10.0) / fSetRatio[1];
					fPos[2] = double((short)(chBuf[16] + chBuf[17] * 0x100) / 10.0);

					//fPosOut[0] = (fPos[0] - GetNewPos(int(fPos[0] * 10), 1) / 10.0/* - fPosOp[0]*/) / fSetRatio[0];
					//fPosOut[1] = (fPos[1] - GetNewPos(int(fPos[1] * 10), 2) / 10.0/* - fPosOp[1]*/) / fSetRatio[1];

					fPosOut[0] = (fPos[0] - fPosOp[0]) / fSetRatio[0];
					fPosOut[1] = (fPos[1] - fPosOp[1]) / fSetRatio[1];
					fPosOut[2] = fPos[2];
					
					if (funRecv)
					{
						bStop[0] = 1 - bMoving[0];
						bStop[1] = 1 - bMoving[1];
						bStop[2] = 1 - bMoving[2];
						funRecv(bStop, bIsZero, bIsSin, bAbs, fPosOut, fSpd);
					}
				}
			}
		}
	}
	
	return 0;
}

BOOL Read(SOCKET nSockID)
{
	SOCKADDR_IN	sAddr;
	int			nLen = sizeof(sAddr);
	char		chBuf[10000];

	static int nCnt = 0;
	
	int	nRecLen = recvfrom((SOCKET)nSockID, chBuf, 10000, 0, (sockaddr *)&sAddr, &nLen);
	if (nRecLen == SOCKET_ERROR)
	{
		return FALSE;
	}
	
// 	if (funRecv)
// 	{
// 		funRecv();
// 	}

	nCnt++;
	
	return TRUE;
}

BOOL Write(char *pchBuf, int nLen)
{
	return (send(sServer, pchBuf, nLen, 0) != SOCKET_ERROR);
}

// ���ڴ�����Ϣ���ڽ��յ�����Ϣ
// #define	DEF_UDP_MSG				WM_USER + 111
// LRESULT CALLBACK MessageWinProc(HWND	hWnd,			// Handle to window
// 								UINT	uMsg,			// Message identifier
// 								WPARAM	wParam,			// First message parameter
// 								LPARAM	lParam)			// Second message parameter
// {
// 	switch (uMsg)
// 	{
// 	case WM_DESTROY:
// 		DestroyWindow(hWnd);
// 		PostQuitMessage(0);
// 		break;
// 		
// 	case DEF_UDP_MSG:
// 		{
// 			switch (lParam)
// 			{
// 			case FD_READ:
// 				Read(wParam);
// 				break;
// 				
// 			case FD_WRITE:
// // 				::MessageBox(hWnd, "Remote Tcp Write", " Notice", MB_ICONINFORMATION);
// 				break;
// 			}
// 		}
// 		break;
// 		
// 	default:
// 		return DefWindowProc(hWnd, uMsg, wParam, lParam);
// 		break;
// 	}
// 	
// 	return 0;
// }
// 
// int MessageWindowInit()
// {
// 	HINSTANCE hInstance = NULL;
// 	hInstance = GetModuleHandle(NULL);
// 	if (hInstance == NULL)
// 	{
// 		return FALSE;
// 	}
// 	
// 	WNDCLASS wndcls;
// 	wndcls.cbClsExtra		= 0;
// 	wndcls.cbWndExtra		= 0;
// 	wndcls.hbrBackground	= (HBRUSH)GetStockObject(BLACK_BRUSH);
// 	wndcls.hCursor			= LoadCursor	(NULL, IDC_CROSS);
// 	wndcls.hIcon			= LoadIcon		(NULL, IDI_APPLICATION);
// 	wndcls.hInstance		= hInstance;
// 	wndcls.lpfnWndProc		= MessageWinProc;
// 	wndcls.lpszClassName	= "UdpMsgRecWnd";
// 	wndcls.lpszMenuName		= NULL;
// 	wndcls.style			= CS_HREDRAW | CS_VREDRAW;
// 	RegisterClass(&wndcls);
// 	
// 	hMsgWnd = CreateWindowEx(0, "UdpMsgRecWnd", "UdpMsgRecWnd", 0, 0, 0, 0, 0, NULL, 0, hInstance, 0);
// 	
// 	return (hMsgWnd != NULL);
// }

int ConnectServer(char *pchIP, int nPort,char *isowned)
{
	WSADATA wsaData;
	if (WSAStartup(MAKEWORD(2, 2), &wsaData))
	{
		return -1;
	}
	
	if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2 )
	{
		return -1; 
	}
	
	// ������������Socket
	SOCKET nServID = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	if (nServID == INVALID_SOCKET)
	{
		// �޷������������׽���
		return -1;
	}
	
	DWORD dwIp;
	if ((dwIp = inet_addr(pchIP))== INADDR_NONE)
	{
		// IP����
		return -1;
	}
	
	// ʹ��TCP/IPЭ��
	SOCKADDR_IN			from	= {0};
	from.sin_family				= AF_INET;
	from.sin_port				= htons(nPort);
	from.sin_addr.S_un.S_addr	= dwIp;

// 	SOCKADDR_IN			local	= {0};
// 	local.sin_family			= AF_INET;
// 	local.sin_port				= htons(nPort + 1);
// 	local.sin_addr.S_un.S_addr	= INADDR_ANY;
// 
// 	int nRecvBuf = 1;
// 	setsockopt(nServID, SOL_SOCKET, SO_REUSEADDR, (char FAR *)nRecvBuf, sizeof(int));
// 	if (bind(nServID, (LPSOCKADDR)&local, sizeof(local)) == SOCKET_ERROR)
// 	{ 
// 		// �޷����ӷ�����
// 		return -5;
// 	}

	if (connect(nServID, (LPSOCKADDR)&from, sizeof(from)) == SOCKET_ERROR)
	{ 
		// �޷����ӷ�����
		return -1;
	}

	//send command to ask motor can be controlled?
	chData[0] = 0xeb;
	chData[1] = 0xFF;
	chData[2] = 0x00;
	chData[3] = GetSum(chData, 3);
	chData[4] = 0xec;

	send((SOCKET)nServID, (char*)chData, 5, 0);
	//wait reply
	SOCKADDR_IN	sAddr;
	int			nLen = sizeof(sAddr);
	char		chBuf[10];

	int nNetTimeout = 3000;//1秒
	setsockopt((SOCKET)nServID, SOL_SOCKET, SO_RCVTIMEO, (char*)&nNetTimeout, sizeof(int));
	int	nRecLen = recvfrom((SOCKET)nServID, chBuf, 10, 0, (sockaddr*)&sAddr, &nLen);
	if (nRecLen == SOCKET_ERROR)
	{
		return CONNECTFAILERROR;
	}

	nNetTimeout = 0;//1秒
	setsockopt((SOCKET)nServID, SOL_SOCKET, SO_RCVTIMEO, (char*)&nNetTimeout, sizeof(int));

	//parse reply
	if (strncmp(chBuf, "yes", 3)==0)
	{
		//有连接,建立连接但被他人使用
		*isowned = 1;
		nThreadRun = 1;
		hThread = (HANDLE)_beginthreadex(NULL, 0, ThreadLoop_UdpClient, NULL, 0, NULL);
		SetThreadPriority(hThread, THREAD_PRIORITY_TIME_CRITICAL);
		return nServID;
	}

	else if (strncmp(chBuf, "no", 2)==0)
	{
		//没连接，正常建立连接
		*isowned = 0;
		nThreadRun = 1;
		hThread = (HANDLE)_beginthreadex(NULL, 0, ThreadLoop_UdpClient, NULL, 0, NULL);
		SetThreadPriority(hThread, THREAD_PRIORITY_TIME_CRITICAL);
		return nServID;
	}
	else
	{

	}

// 	WSAAsyncSelect(nServID, hMsgWnd, DEF_UDP_MSG, FD_ALL_EVENTS);

	
	*isowned = -1;
	return nServID;
}

void GetFileName(char *pchOutName, char *pchInName)
{
	::GetModuleFileName(NULL, pchOutName, MAX_PATH);
	
	int nLen = strlen(pchOutName);
	while (pchOutName[--nLen] != '\\');
	pchOutName[++nLen] = 0;
	
	strcat(pchOutName, pchInName);
}

//void InfoLoad()
//{
//	char chName[MAX_PATH];
//	GetFileName(chName, "Config.ini");
//	_INI_GetPath(chName);
//
//	int nDevice;
//	_INI_GetKeyValInt("System",	"Device", nDevice);
//	if (nDevice <= 0 || nDevice > 20)
//	{
//		nDevice = 1;
//	}
//
//	char chDevice[10];
//	sprintf(chDevice, "Device%d", nDevice);
//
//	char chData[10];
//	for (int i=0; i<11; i++)
//	{
//		sprintf(chData, "XOffSet%d", i + 1);
//		_INI_GetKeyValInt(chDevice,	chData, nXOffSet[i]);
//	}
//	for (int i=0; i<11; i++)
//	{
//		sprintf(chData, "YOffSet%d", i + 1);
//		_INI_GetKeyValInt(chDevice,	chData, nYOffSet[i]);
//	}
//}

BOOL APIENTRY DllMain(HANDLE hModule, 
					  DWORD  ul_reason_for_call, 
					  LPVOID lpReserved)
{
    switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
		//InfoLoad();
// 		if (hMsgWnd)
// 		{
// 			DestroyWindow(hMsgWnd);
// 		}
// 		MessageWindowInit();
		break;
		
	case DLL_THREAD_ATTACH:
		break;
		
	case DLL_THREAD_DETACH:
		break;
		
	case DLL_PROCESS_DETACH:
// 		if (hMsgWnd)
// 		{
// 			DestroyWindow(hMsgWnd);
// 			hMsgWnd = NULL;
// 		}
		break;
    }
    return TRUE;
}

// �������ܣ����˶�����װ�ý�������
// �������룺ID���豸IDAddr������IP
// ����ֵ��handle������0Ϊ�豸���ƾ��С��0Ϊ����ʧ��
DEF_API_EXP MotionOpen(int ID, char* Addr, int nPort,char *isowned)
{
	if (sServer > 0)
	{
		return sServer;
	}

	int nRtn = ConnectServer(Addr, nPort,isowned);
	if (nRtn <= 0)
	{
		WSACleanup();
		return nRtn;
	}

	sServer = nRtn;
	return sServer;
}

// �������ܣ��Ͽ����˶�����װ�õ�����
// �������룺handle���豸���ƾ��
// ����ֵ��1-�ɹ�-1-ʧ��
DEF_API_EXP MotionClose(int handle)
{
	if (handle != (int)sServer && handle <= 0)
	{
		return -1;
	}

	chData[0] = 0xeb;
	chData[1] = 0xFE;
	chData[2] = 0x00;
	chData[3] = GetSum(chData, 3);
	chData[4] = 0xec;

	Write((char *)chData,5);


	nThreadRun = 0;
	
	// �ر��׽���
	closesocket(sServer);
	
	// ��ֹ�׽��ֿ��ʹ��
	WSACleanup();
	
	if (hThread)
	{
		CloseHandle(hThread);
		hThread = NULL;
	}

	sServer = 0;
	
	return 1;
}

// �������ܣ����㣬���ص���е��λ
// �������룺handle���豸���ƾ��
// ����ֵ��1-�ɹ�,-1-ʧ��
DEF_API_EXP MotionBackZero(int handle, short iAxis)
{
	if (handle != (int)sServer && handle <= 0)
	{
		return -1;
	}
	
	if (iAxis < 0 || iAxis > 3)
	{
		return -2;
	}
	
	chData[0] = 0xeb;
	chData[1] = 0x01;
	chData[2] = (BYTE)iAxis;
	chData[3] = GetSum(chData, 3);
	chData[4] = 0xec;
	
	fPosOp[0] = 0;
	fPosOp[1] = 0;
	fPosOp[2] = 0;
	
	Write((char *)chData, 5);
	
	return 1;
}

// �������ܣ�ֹͣ�˶�
// �������룺handle���豸���ƾ��
// ����ֵ��1-�ɹ�-1-ʧ��
DEF_API_EXP MotionStop(int handle)
{
	if (handle != (int)sServer && handle <= 0)
	{
		return -1;
	}
	
	chData[0] = 0xeb;
	chData[1] = 0x03;
	chData[2] = 0x00;
	chData[3] = GetSum(chData, 3);
	chData[4] = 0xec;
	
	Write((char *)chData, 5);
	
	return 1;
}

DEF_API_EXP MotionGetPrior(int handle)
{
	if (handle != (int)sServer && handle <= 0)
	{
		return -1;
	}

	chData[0] = 0xeb;
	chData[1] = 0xFD;
	chData[2] = 0x00;
	chData[3] = GetSum(chData, 3);
	chData[4] = 0xec;

	Write((char*)chData, 5);

	return 1;
}

DEF_API_EXP MotionClearZero(int handle)
{
	if (handle != (int)sServer && handle <= 0)
	{
		return -1;
	}
	
	//fPosOp[0] += (fPos[0]-fPosOp[0]);
	//fPosOp[1] += (fPos[1]-fPosOp[1]);


	fPosOp[2] = 0;
	
	chData[0] = 0xeb;
	chData[1] = 0x07;
	chData[2] = 0x00;
	chData[3] = GetSum(chData, 3);
	chData[4] = 0xec;
	
	Write((char *)chData, 5);
	
	return 1;
}

// �������ܣ��ж��Ƿ�ֹͣ
// �������룺handle���豸���ƾ�� iAxis����ţ�1Ϊ��λ��2Ϊ������3Ϊ��ת
// ����ֵ��1-�ɹ�-1-ʧ��
DEF_API_EXP MotionIsStop(int handle, short iAxis)
{
	if (handle != (int)sServer && handle <= 0)
	{
		return -1;
	}
	
	if (iAxis < 1 || iAxis > 3)
	{
		return -1;
	}
		
	return (1 - bMoving[iAxis - 1]);
}

// �������ܣ����루��λmm����Ƕȣ���λ�㣩�Ļ����ϵ
// �������룺handle���豸���ƾ��fRatio��ϵ�����飬�ֱ�Ϊ��λ����������ת
// ����ֵ��1-�ɹ�-1-ʧ��
DEF_API_EXP MotionSetRatio(int handle, float fRatio[3])
{
	chData[0] = 0xeb;
	chData[1] = 0x02;
	chData[2] = 0x02;
	chData[3] = 0xec;
	Write((char *)chData, 4);

	for (int i=0; i<2; i++)
	{
		if (fRatio[i] <= 0.1 || fRatio[i] > 5000)
		{
			return -1;
		}

		fSetRatio[i] = fRatio[i];
	}
	
	return 1;
}

// �������ܣ��˶���ĳһ�ض�λ��
// �������룺
//		handle	�豸���ƾ��
//		iAxis	��ţ�1Ϊ��λ��2Ϊ������3Ϊ��ת
//		fSetPos	λ�ã���λ��
//		fSetVel	�ٶȣ���λ��/s
//		bIsAbs	�˶���ʽ��1Ϊ�����˶���0Ϊ����˶�
// ����ֵ��1-�ɹ�-1-ʧ��
DEF_API_EXP MotionMoveToPos(int handle, short iAxis, double fSetPos, double fSetVel, int bIsAbs)
{
	if (handle != (int)sServer && handle <= 0)
	{
		return -1;
	}

	if (iAxis < 1 || iAxis > 3)
	{
		return -1;
	}

	if (bIsAbs < 0 || bIsAbs > 1)
	{
		return -1;
	}

	if (bIsZero[iAxis - 1] != 2)
	{
		return -1;
	}
	
	bAbs[iAxis - 1] = bIsAbs;
	if (bIsAbs == 0)
	{
// 		if (bMoving[iAxis - 1])
// 		{
// 			return -1;
// 		}

		fSetPos += fPos[iAxis - 1] / fSetRatio[iAxis - 1];
	}
	else
	{

		if (iAxis == 1 || iAxis == 2)
		{
			fSetPos += (fPosOp[iAxis - 1] / fSetRatio[iAxis - 1]);
		}
	}

	chData[0] = 0xeb;
	chData[1] = 0x04;
	chData[2] = (BYTE)iAxis;
	
	if (iAxis != 3)
	{
		fSetPos = fSetPos * 10.0 * fSetRatio[iAxis - 1];
	}
	else if(iAxis == 3)
	{
		fSetPos = fSetPos * 10.0;
	}
	
	if (fSetPos >= 0)
	{
		fSetPos += 0.01;
	}
	else
	{
		fSetPos -= 0.01;
	}

	int nSetPos = (int)fSetPos;
	//_dc.nVal = nSetPos + GetNewPos(nSetPos, iAxis);
		_dc.nVal = nSetPos;
	memcpy(chData + 3, _dc.chVal, 4);
	
	if (iAxis != 3)
	{
		fSetVel = fSetVel * 10.0 * fSetRatio[iAxis - 1];
	}
	if (fSetVel >= 0)
	{
		fSetVel += 0.01;
	}
	else
	{
		fSetVel -= 0.01;
	}
	_dc.nVal = (int)fSetVel;
	memcpy(chData + 7, _dc.chVal, 4);

	chData[11] = GetSum(chData, 11);
	chData[12] = 0xec;
	
	Write((char *)chData, 13);
	
	return 1;
}

// �������ܣ��˶���ĳһ�ض�λ��
// �������룺
// 		handle���豸���ƾ��
// 		iAxis����ţ�1Ϊ��λ��2Ϊ������3Ϊ��ת
// 		bIsAbs���˶���ʽ��1Ϊ�����˶���0Ϊ����˶�
// ���������fPosition����ǰλ�ã���λ��
// ����ֵ��1-�ɹ�-1-ʧ��
DEF_API_EXP MotionGetPos(int handle, short iAxis, int &bIsAbs, double &fPosition)
{
	if (handle != (int)sServer && handle <= 0)
	{
		return -1;
	}
	
	if (iAxis < 1 || iAxis > 3)
	{
		return -1;
	}

	bIsAbs = bAbs[iAxis - 1];
	fPosition = fPosOut[iAxis - 1];
	
	return 1;
}

DEF_API_EXP MotionGetVel(int handle, short iAxis, int &bIsAbs, double &fVelocity)
{
	if (handle != (int)sServer && handle <= 0)
	{
		return -1;
	}
	
	if (iAxis < 1 || iAxis > 3)
	{
		return -1;
	}
	
	bIsAbs = bAbs[iAxis - 1];
	fVelocity = fSpd[iAxis - 1];
	
	return 1;
}

// �������ܣ������˶�
// �������룺
// 		handle���豸���ƾ��
// 		iAxis����ţ�1Ϊ��λ��2Ϊ������3Ϊ��ת
// 		fSetFreq��Ƶ�ʣ���λHZ
// 		fSetAmp�����ȣ���λ��
// 		iSetTime���˶�ʱ�䣬��λs
// ����ֵ��1-�ɹ�-1-ʧ��
DEF_API_EXP MotionSetSineMove(int handle, short iAxis, double fSetFreq, double fSetAmp, int iSetTime)
{
	if (handle != (int)sServer && handle <= 0)
	{
		return -1;
	}
	
	if (iAxis < 1 || iAxis > 2)
	{
		return -1;
	}
	
	if (bIsZero[iAxis - 1] != 2)
	{
		return -1;
	}

	int nCycle	= (int)(1000.0 / fSetFreq);
	int nAmp	= (int)(fSetAmp * fSetRatio[iAxis - 1] * 10.0);
	int nCnt	= iSetTime;

	double fTemp = nAmp / 10.0 * pow(2000 * 3.1415926 / nCycle, 2);
	if (fTemp >= 36000.0)
	{
		return -1;
	}
	
	chData[0] = 0xeb;
	chData[1] = 0x05;
	chData[2] = (BYTE)iAxis;
	
	_dc.nVal = nCycle;
	memcpy(chData + 3, _dc.chVal, 4);
	
	_dc.nVal = nAmp;
	memcpy(chData + 7, _dc.chVal, 4);
	
	_dc.nVal = nCnt;
	memcpy(chData + 11, _dc.chVal, 4);
	
	chData[15] = GetSum(chData, 15);
	chData[16] = 0xec;
	
	Write((char *)chData, 17);

	bMoving[iAxis - 1] = 1;
	
	return 1;
}


// �������ܣ����������ٶ�
// �������룺handle���豸��
// ����ֵ��1-�ɹ�,-1-ʧ��
DEF_API_EXP MotionSetTimer(int handle, int nTimer)
{
	if (nTimer < 5 || nTimer > 20)
	{
		return -1;
	}

	chData[0] = 0xeb;
	chData[1] = 0x08;
	chData[2] = (BYTE)nTimer;
	chData[3] = GetSum(chData, 3);
	chData[4] = 0xec;
	
	Write((char *)chData, 5);
	
	return 1;
}

// �������ܣ����������ٶ�
// �������룺handle���豸���ƾ��fMaxAcc�����ٶ����飬�ֱ�Ϊ��λ����������ת��
// ����ֵ��1-�ɹ�,-1-ʧ��
DEF_API_EXP MotionSetMaxAcc(int handle, float fMaxAcc[3])
{
	if (handle != (int)sServer && handle <= 0)
	{
		return -1;
	}

	chData[0] = 0xeb;
	chData[1] = 0x06;
	
	fMaxAcc[0] *= (float)fSetRatio[0];
	if (fMaxAcc[0] < 7000 || fMaxAcc[0] > 10000)
	{
		return -1;
	}
	_dc.nVal = (int)fMaxAcc[0];
	memcpy(chData + 2, _dc.chVal, 4);
	
	fMaxAcc[1] *= (float)fSetRatio[1];
	if (fMaxAcc[1] < 7000 || fMaxAcc[1] > 10000)
	{
		return -1;
	}
	_dc.nVal = (int)fMaxAcc[1];
	memcpy(chData + 6, _dc.chVal, 4);
	
	_dc.nVal = 0;//(int)fMaxAcc[2];
	memcpy(chData + 10, _dc.chVal, 4);
	
	chData[14] = GetSum(chData, 14);
	chData[15] = 0xec;
	
	Write((char *)chData, 16);
	
	return 1;
}

